// i.d(t, { _: () => MeshData })
import Data from "../object/Data"
import * as THREE from "three"
import AnimatedNumber from "../object/AnimatedNumber"
import { createSubscription } from "../utils/Subscription"
import RoomValueMap from "../three/RoomValueMap"
import Floor from "../object/Floor"
const l = [-5, -5, -5, 5, 5, 5]
interface RoomDataItem {
  boundingBox: THREE.Box3
  meshGroup: number
  parentMeshGroup: number
}
export default class MeshData extends Data {
  bounds: THREE.Box3
  center: THREE.Vector3
  size: THREE.Vector3
  _meshGroups: {
    floors: Set<Partial<Floor>>
    floorIds: Record<string, string>
    rooms: RoomValueMap<RoomDataItem>
    roomIds: RoomValueMap<string>
    roomsByFloor: Map<
      number,
      {
        meshGroup: number
        meshSubgroup: number
      }[]
    >
  }
  meshGroupVisuals: { floorOpacity: Map<any, any>; roomFadeDist: RoomValueMap<number> }
  meshIdCallbacks: Set<Function>
  meshTextureOpacity: AnimatedNumber
  constructor(opacity: number, bounds = l) {
    super()
    this.name = "mesh-data"
    this.bounds = new THREE.Box3()
    this.center = new THREE.Vector3()
    this.size = new THREE.Vector3()
    this._meshGroups = {
      floors: new Set(),
      floorIds: {},
      rooms: new RoomValueMap(),
      roomIds: new RoomValueMap(),
      roomsByFloor: new Map()
    }
    this.meshGroupVisuals = {
      floorOpacity: new Map(),
      roomFadeDist: new RoomValueMap()
    }
    this.meshIdCallbacks = new Set()
    this.meshTextureOpacity = new AnimatedNumber(opacity)
    this.bounds.setFromArray(bounds)
    this.bounds.getCenter(this.center)
    this.bounds.getSize(this.size)
  }
  get meshGroups() {
    return this._meshGroups
  }
  meshSubGroupsFromPoint(e) {
    const t: { meshGroup: number; meshSubgroup: number }[] = []
    for (const { meshGroup, meshSubgroup, value } of this.meshGroups.rooms) value.boundingBox.containsPoint(e) && t.push({ meshGroup, meshSubgroup })
    return t
  }
  onMeshIdsUpdated(e: Function) {
    return createSubscription(
      () => this.meshIdCallbacks.add(e),
      () => this.meshIdCallbacks.delete(e),
      !0
    )
  }
  setMeshIds(e) {
    if (e.roomIdMap) for (const { meshGroup: t, meshSubgroup: i, value: n } of e.roomIdMap) this.meshGroups.roomIds.set(t, i, n)
    e.floorIdMap?.forEach((e, t) => {
      this.meshGroups.floorIds[t] = e
    })
    for (const e of this.meshIdCallbacks.values()) e(this)
  }
}
